# Sync.up

A simple system to keep a repository in sync with an upstream repository and then push any changes to a separate repository. I use this to clone upstream repositories from Github, since Microsoft bought it, updating a local clone of a repo and then pushing those changes to an online Git hosting service.

## Manual

To use `sync.up` manually:

1. Find a repo on Github that you want to mirror. From now on, this repo is known as `upstream`.
1. Create an empty repo on some other Git hosting service like http://gitlab.com, http://notabug.org, or your own private server. 
1. Clone the *empty* repo from your remote host:
       $ git clone git@github.com:notklaatu/foo.git foo.git
1. Add the upstream URL to your local clone:
       $ git remote add upstream git@github.com:notklaatu/foo.git
1. The first time you push to your empty remote, you must do so manually, so that you are telling the remote that you are sending it a new branch:
       $ git push -u upstream master
1. After that, you can use `sync.up` to pull from upstream into your local clone and push to your remote:
       $ ./sync.up foo.git 


## Automation

More likely, you want `sync.up` to be automated. You can do this with a simple cron job. Edit your crontab with the `crontab -e` command and add either:

    @weekly path/to/sync.up path/to/foo.git

or

    0 0 * * 0 path/to/sync.up path/to/foo.git

For a weekly update.

See http://crontab.guru for more crontab syntax.


## Known issues

There are some quirks when mirroring a repository. Here are some things that might happen, and how to fix them:

### Untracked branch on remote

If you use an import tool to import a repo from Github into your new remote, then `sync.up` works right away. However, if you create an empty repo on a remote server, then that repo has no knowledge of what your local repo contains. That's why you have to do your first push manually:

    $ git push -u upstream master

The `-u` option tells your remote Git repo (`upstream`, in this example) to start tracking the `master` branch. If you do not do this before attempting to use `sync.up`, then `sync.up` fails. All is not lost; just do the manual `push -u` and then you can use `sync.up` from then on.

### Mismatched names for "master" branch

If the upstream repository is not called `master`, then `sync.up` fails.

You can fix this by defining the branch names involved. The easiest way to do this is to edit the `.git/config` file in your repository directly. Assuming the upstream "master" branch is called `develop` but your local copy is called `master`, you see this in your config file:

    ...
    [remote "origin"]
        url = git@gitlab.com:notklaatu/grav.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [remote "upstream"]
	url = git@github.com:getgrav/grav.git
	fetch = +refs/heads/*:refs/remotes/origin/*

Set the `upstream` branch to `develop`:

    [branch "develop"]
        remote = upstream
	merge = refs/heads/develop

And set your local master branch to `master`:

    [branch "master"]
        remote = origin
        merge = refs/heads/master


## Bugs

If you find other issues, report them to klaatu@member dot fsf dot org.
